// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: implementation of  CXFormElementFormControlInput.
//   $Id$

// FormControl.cpp: implementation of the CFormControl class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"

#include "FormControlInputUI.h"
#include "XFormsXFormsElement.h"
#include "tags.h"

//used in CXFormsElementFormControlInput::copyStyle
//	more efficient than allocating and deallocating
//	every time.
const CComBSTR g_bsControlNameLabel(L"label");
const CComBSTR g_bsControlNameAlert(L"alert");


//////////////////////////////////////////////////////////////////////
// CXFormsElementFormControlInput
//////////////////////////////////////////////////////////////////////

CXFormsElementFormControlInput::CXFormsElementFormControlInput()
	:m_didPutLabel(0)
	,m_didPutAlert(0)
{
}

CXFormsElementFormControlInput::~CXFormsElementFormControlInput()
{
}

HRESULT CXFormsElementFormControlInput::put_caption(const BSTR bsCaption)
{
	if(m_bNewMethod && m_pControlWin)
	{
//*
		BSTR bsFnName =::SysAllocString(L"put_label");
	//	BSTR bsParam =::SysAllocString(bsCaption);//L"insert a new Groupinsert a new Group");
		CComVariant vtArg(bsCaption);
		DISPPARAMS params = {&vtArg,0,1,0};
		CComVariant vt;
	
		HRESULT hr = UIExecFunction(bsFnName,&params,&vt,m_didPutLabel);
		::SysFreeString(bsFnName);
		//::SysFreeString(bsParam);
//*/
/*
		CStringW sCaption(bsCaption);
		escapeJScriptArgument(sCaption);
		CStringW sScript;
		sScript.Format(L"put_label('%s')",sCaption);
		BSTR bsScript = sScript.AllocSysString();
		HRESULT hr = UIExecScript(bsScript);
		::SysFreeString(bsScript);
/*/		return hr;
	}
	else if(m_pCaptionUI)
		return m_pCaptionUI->put_innerHTML(bsCaption);
	else
		return S_FALSE;
}

HRESULT CXFormsElementFormControlInput::get_caption(BSTR * psCaption)
{
	if(m_pCaptionUI)
		return m_pCaptionUI->get_innerHTML(psCaption);
	else
		return S_FALSE;
}

HRESULT CXFormsElementFormControlInput::put_alert(const BSTR bsAlert)
{
	HRESULT hr = S_FALSE;
	if(m_bNewMethod && m_pControlWin) {
		CComVariant vtArg(bsAlert);
		DISPPARAMS params = {&vtArg, 0, 1, 0};
		CComVariant vt;
		CComBSTR sFuncName(L"put_alert");
		hr = UIExecFunction(sFuncName, &params, &vt,m_didPutAlert);
	} else if(m_pCaptionUI)
		hr = m_pCaptionUI->put_innerHTML(bsAlert);
	return hr;
}

HRESULT CXFormsElementFormControlInput::get_alert(BSTR *psAlert)
{
	if(m_pCaptionUI)
		return m_pCaptionUI->get_innerHTML(psAlert);
	else
		return S_FALSE;
}

HRESULT CXFormsElementFormControlInput::put_hint(const BSTR bsHint)
{
	HRESULT hr = S_FALSE;
	if(m_bNewMethod && m_pControlWin)
	{
		CComVariant vtArg(bsHint);
		DISPPARAMS params = {&vtArg,0,1,0};
		CComVariant vt;
		DISPID did = 0;
		CComBSTR sFuncName(L"put_hint");
		hr = UIExecFunction(sFuncName,&params,&vt,did);
	}
	else if(m_pCaptionUI)
		hr = m_pCaptionUI->put_innerHTML(bsHint);
	return hr;
}

HRESULT CXFormsElementFormControlInput::resetScriptDispID() {
	m_didPutLabel = m_didPutAlert = 0;
	return __super::resetScriptDispID();
}

HRESULT CXFormsElementFormControlInput::get_hint(BSTR * psHint)
{
	if(m_pMain)
		return m_pMain->get_title(psHint);
	else if(m_pControl)
		return m_pControl->get_title(psHint);
	else
		return S_FALSE;
}


HRESULT CXFormsElementFormControlInput::copyStyle()
{
	HRESULT hr = S_OK;
	
	//get the children of the masterElement
	CComQIPtr<IHTMLElementCollection> pColl;
	{
		CComPtr<IDispatch> pDisp;
		CComPtr<IHTMLElement> pMaster;
		GetMasterElement(&pMaster);
		
		if(pMaster)
		{
			pMaster->get_children(&pDisp);
			pColl = pDisp;
		}
		pDisp.Release();
	}
	
	//Get a document object for getElementById
/*	CComQIPtr<IHTMLDocument3> pDoc;
	{
		IHTMLDocument * pViewLinkDoc = NULL;
		hr = GetViewlinkDoc(&pViewLinkDoc);

		if(SUCCEEDED(hr))
			pDoc = pViewLinkDoc;
		::safeRelease(pViewLinkDoc);
	}
*/

	if(pColl) {
		//get the first caption element.  This is so awkward
		CComPtr<IDispatch> pDisp;
		pColl->tags(_variant_t(TAG_CAPTION),&pDisp);
		CComQIPtr<IHTMLElementCollection> pColl2 = pDisp;
		pDisp.Release();

		if(pColl2) {
			hr = pColl2->item(_variant_t((long)0,VT_I4),_variant_t((long)0,VT_I4),&pDisp);
			if(SUCCEEDED(hr) && pDisp)
			{
				CComQIPtr<IHTMLElement2> pEl = pDisp;
				pDisp.Release();
				if(pEl) {
					CComBSTR s;
					CComPtr<IHTMLStyle> pRS;
					//remove the runtimestyle change
					CComQIPtr<IHTMLElement2>(pEl)->get_runtimeStyle(&pRS);
					const CComBSTR sNothing;
					const CComBSTR sNone(L"hidden");
					pRS->put_visibility(sNothing);
					CBinaryBehavior::getCurrentStyleAsText(pEl,&s);
					pRS->put_visibility(sNone);
					put_style(g_bsControlNameLabel,s);
				}
			}
		}

		//Get the alert.
		pColl->tags(_variant_t(TAG_ALERT), &pDisp);
		pColl2 = pDisp;
		pDisp.Release();
		if(pColl2) {
			hr = pColl2->item(_variant_t(0L, VT_I4), _variant_t(0L, VT_I4), &pDisp);
			if(SUCCEEDED(hr) && pDisp) {
				CComQIPtr<IHTMLElement2> pEl = pDisp;
				pDisp.Release();
				if(pEl) {
					CComBSTR s;
					CBinaryBehavior::getCurrentStyleAsText(pEl, &s);
					put_style(g_bsControlNameAlert, s);
				}
			} else {
				CComBSTR s(L"display:none;"); 
				put_style(g_bsControlNameAlert, s);			
			}
		}
	} else
		hr = S_FALSE;
	return CXFormsElementSingleNodeBinding::copyStyle();
}

HRESULT CXFormsElementFormControlInput::getSignificantDescendentNodes(IHTMLDocument3 * pDoc3)
{
	//Potentially we could run getElementById every time we call put/get
	//	rather than store, but I would prefer to stick with the current
	//	model before making radical changes.
	if(!m_bNewMethod)
	{
		CComBSTR bsCaption(L"caption");
		pDoc3->getElementById(bsCaption, &m_pCaptionUI);
	}	
	return CXFormsElementSingleNodeBinding::getSignificantDescendentNodes(pDoc3);
}


HRESULT CXFormsElementFormControlInput::InitBehaviour()
{
	HRESULT hr =  __super::InitBehaviour();

	
	return hr;
}
